package com.mrd.gtimp.business.action;


import com.mrd.constant.MsgConstants;
import com.mrd.exception.QueryException;
import com.mrd.framework.config.web.json.Result;
import com.mrd.framework.config.web.json.annotation.JField;
import com.mrd.framework.config.web.json.annotation.Json;
import com.mrd.framework.ui.Jqgrid;
import com.mrd.framework.ui.filter.Filter;
import com.mrd.framework.ui.filter.SearchRule;
import com.mrd.framework.ui.filter.SearchRuleOption;
import com.mrd.framework.utils.HttpUtils;
import com.mrd.gtimp.base.entity.Company;
import com.mrd.gtimp.base.service.CompanyBiz;
import com.mrd.gtimp.business.entity.FundFlow;
import com.mrd.gtimp.business.entity.FundReport;
import com.mrd.gtimp.business.service.FundFlowBiz;
import com.mrd.gtimp.business.service.FundReportBiz;
import com.mrd.gtimp.v2.dto.FundCustomerBizReport;
import com.mrd.gtimp.v2.fund.FundFinancialTypeEnum;
import com.mrd.util.LoginUtil;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

@Controller
@RequestMapping("/fund")
public class FundReportAction {
    @Resource
    private FundReportBiz biz;

    @RequestMapping("/report-main")
    public String main() {
        if ("CC".equals(LoginUtil.getLoginUser().getCompany().getType())) {
            return "/gtimp/fundReport/sup_main";
        }
        return "/gtimp/fundReport/customer_main";
    }

    @RequestMapping("/report-managerMain")
    public String managerMain() {
        return "/gtimp/fundReport/manager_main";
    }

    @RequestMapping("/report-bizMain")
    public String bizMain() {
        return "/gtimp/fundReport/biz_main";
    }

    @RequestMapping("/report-managerBizMain")
    public String managerBizMain() {
        return "/gtimp/fundReport/manager_biz_main";
    }

    @RequestMapping("/report-qpreportMain")
    public String qpreportMain() {
        return "/gtimp/fundReport/qpreport";
    }

    @RequestMapping("/report-managerCustomerBizMain")
    public String managerCustomerBizMain() {
        return "/gtimp/fundReport/manager_customer_biz_main";
    }

    @RequestMapping("/report-view")
    public String view(FundReport fundReport) {
        HttpUtils.getRequest().setAttribute("id", HttpUtils.getRequest().getParameter("id"));
        try {
            fundReport = biz.findEntityById(HttpUtils.getRequest().getParameter("id"));
            List<Object> result = new ArrayList<Object>();
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Map<String, Object> param = new HashMap<String, Object>();
                param.put("supComId", LoginUtil.getLoginUser().getCompany().getId());
                param.put("startDate", sdf.format(fundReport.getPreRegDate()));
                param.put("endDate", sdf.format(fundReport.getRegDate()));
                result = biz
                        .findObjectBySql("select count(*)"
                                + " from t_biz_base_business b, t_biz_declaration d, t_sys_company c"
                                + " where b.id = d.id and b.customer_com_id = c.com_id and d.state not in ('DS00', 'DS03')"
                                + " and b.confirm_time > to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                + " and b.confirm_time <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                + " and b.sup_id =:supComId", 0, 500, param);
            } catch (Exception e) {
                e.printStackTrace();
            }
            HttpUtils.getRequest().setAttribute("totalBizCount", result.size() > 0 ? result.get(0) : "获取失败");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "/gtimp/fundReport/view";
    }

    @RequestMapping("/report-findManagerCustomerBizReport2")
    @ResponseBody
    @Json({@JField("com_name"), @JField("amount"), @JField("fundAmount")})
    public Page<FundCustomerBizReport> findManagerCustomerBizReport2(Jqgrid jqgrid) {
        List<FundCustomerBizReport> customerBizReports = new ArrayList<>();
        Filter filters = jqgrid.getFilters();
        String startDate = "";
        String endDate = "";
        if (filters == null) {
            return null;
        }
        for (SearchRule rule : filters.getRules()) {
            if (rule.getField().equals("regDate")) {
                if (rule.getOp().equals(SearchRuleOption.ge)) {
                    startDate = rule.getData().toString();
                }
                if (rule.getField().equals("regDate")) {
                    if (rule.getOp().equals(SearchRuleOption.le)) {
                        endDate = rule.getData().toString();
                    }
                }
            }
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (StringUtils.isEmpty(startDate)) {
                startDate = sdf.format(new Date(0));
            }
            if (StringUtils.isEmpty(endDate)) {
                endDate = sdf.format(new Date());
            }
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("startDate", startDate);
            param.put("endDate", endDate);
            List<Object> result = biz
                    .findObjectBySql("select count(*), c.com_name"
                                    + " from t_biz_base_business b, t_biz_declaration d, t_sys_company c"
                                    + " where b.id = d.id and b.customer_com_id = c.com_id and d.state not in ('DS00', 'DS03')"
                                    + " and b.confirm_time > to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                    + " and b.confirm_time <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                    + " group by c.com_name",
                            jqgrid.getPage().getPageNumber() + 1, jqgrid.getPage().getPageSize(), param);
            List<Object> fundResult = biz
                    .findObjectBySql("select sum(amount), c.com_name from T_BIZ_FUND_FLOW t,t_sys_company c "
                                    + " where t.com_id=c.com_id "
                                    + " and c.com_type='CL'"
                                    + " and t.reg_date > to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                    + " and t.reg_date <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                    + " and t.bill_no in("
                                    + " select bill_no from T_BIZ_FUND_FLOW "
                                    + " where ie_type='DC_PAY'" + " ) group by c.COM_NAME",
                            jqgrid.getPage().getPageNumber() + 1, jqgrid.getPage().getPageSize(), param);
            Map<String, String> fundMap = new HashMap<String, String>();
            for (Object object : fundResult) {
                Object[] objs = (Object[]) object;
                fundMap.put(objs[1].toString(), objs[0].toString());
            }
            for (Object object : result) {
                Object[] objs = (Object[]) object;
                FundCustomerBizReport d = new FundCustomerBizReport(objs[1].toString(), objs[0].toString());
                d.setFundAmount(fundMap.get(objs[1].toString()) == null ? "0.0" : fundMap
                        .get(objs[1].toString()));
                customerBizReports.add(d);
            }
            Page<FundCustomerBizReport> page = new PageImpl<>(customerBizReports);
            return page;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping("/report-findManagerBizReport2")
    @ResponseBody
    @Json({@JField("com_name"), @JField("amount"), @JField("fundAmount")})
    public Page<FundCustomerBizReport> findManagerBizReport2(Jqgrid jqgrid) {
        Filter filters = jqgrid.getFilters();
        List<FundCustomerBizReport> customerBizReports = new ArrayList<>();
        String startDate = "";
        String endDate = "";
        if (filters == null) {
            return null;
        }
        for (SearchRule rule : filters.getRules()) {
            if (rule.getField().equals("regDate")) {
                if (rule.getOp().equals(SearchRuleOption.ge)) {
                    startDate = rule.getData().toString();
                }
                if (rule.getField().equals("regDate")) {
                    if (rule.getOp().equals(SearchRuleOption.le)) {
                        endDate = rule.getData().toString();
                    }
                }
            }
        }
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            if (StringUtils.isEmpty(startDate)) {
                startDate = sdf.format(new Date(0));
            }
            if (StringUtils.isEmpty(endDate)) {
                endDate = sdf.format(new Date());
            }
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("startDate", startDate);
            param.put("endDate", endDate);
            List<Object> result = biz
                    .findObjectBySql("select count(*), c.com_name"
                                    + " from t_biz_base_business b, t_biz_declaration d, t_sys_company c"
                                    + " where b.id = d.id and b.sup_id = c.com_id and d.state not in ('DS00', 'DS03')"
                                    + " and b.confirm_time > to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                    + " and b.confirm_time <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                    + " group by c.com_name",
                            jqgrid.getPage().getPageNumber() + 1, jqgrid.getPage().getPageSize(), param);
            List<Object> fundResult = biz
                    .findObjectBySql("select sum(amount), c.com_name from T_BIZ_FUND_FLOW t,t_sys_company c "
                                    + " where t.com_id=c.com_id "
                                    + " and c.com_type='CC'"
                                    + " and t.reg_date > to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                    + " and t.reg_date <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                    + " and t.bill_no in("
                                    + " select bill_no from T_BIZ_FUND_FLOW "
                                    + " where ie_type='DC_INCOME'" + " ) group by c.COM_NAME",
                            jqgrid.getPage().getPageNumber() + 1, jqgrid.getPage().getPageSize(), param);
            Map<String, String> fundMap = new HashMap<String, String>();
            for (Object object : fundResult) {
                Object[] objs = (Object[]) object;
                fundMap.put(objs[1].toString(), objs[0].toString());
            }
            for (Object object : result) {
                Object[] objs = (Object[]) object;
                FundCustomerBizReport d = new FundCustomerBizReport(objs[1].toString(), objs[0].toString());
                d.setFundAmount(fundMap.get(objs[1].toString()) == null ? "0.0" : fundMap
                        .get(objs[1].toString()));
                customerBizReports.add(d);
            }
            Page<FundCustomerBizReport> page = new PageImpl<>(customerBizReports);
            return page;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping("/report-findQPReport2")
    @ResponseBody
    @Json({@JField("com_name"), @JField("amount")})
    public Page<FundCustomerBizReport> findQPReport2(Jqgrid jqgrid) {
        Filter filters = jqgrid.getFilters();
        List<FundCustomerBizReport> customerBizReports = new ArrayList<>();
        String startDate = "";
        String endDate = "";
        if (null != filters && filters.getRules().size() > 0) {
            for (SearchRule rule : filters.getRules()) {
                if (rule.getField().equals("regDate")) {
                    if (rule.getOp().equals(SearchRuleOption.ge)) {
                        startDate = rule.getData().toString();
                    }
                    if (rule.getField().equals("regDate")) {
                        if (rule.getOp().equals(SearchRuleOption.le)) {
                            endDate = rule.getData().toString();
                        }
                    }
                }
            }
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                if (StringUtils.isEmpty(startDate)) {
                    startDate = sdf.format(new Date(0));
                }
                if (StringUtils.isEmpty(endDate)) {
                    endDate = sdf.format(new Date());
                }
                if (startDate.length() == 10) {
                    startDate += " 00:00:00";
                }
                if (endDate.length() == 10) {
                    endDate += " 23:59:59";
                }
                Map<String, Object> param = new HashMap<String, Object>();
                param.put("startDate", startDate);
                param.put("endDate", endDate);
                List<Object> result = biz
                        .findObjectBySql("select count(*), c.com_name"
                                + " from t_biz_base_business b, t_biz_declaration d, t_sys_company c"
                                + " where b.id = d.id and b.sup_id = c.com_id "
                                + " and b.qpscsj is not null and b.qpdrsj >= to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                + " and b.qpdrsj <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                + " AND D.STATE<>'DS03' AND D.STATE<>'DS030' "
                                + " group by c.com_name", 0, 1000, param);
                List<Object> fundResult = biz
                        .findObjectBySql("select sum(amount), c.com_name from T_BIZ_FUND_FLOW t,t_sys_company c "
                                + " where t.com_id=c.com_id "
                                + " and c.com_type='CC'"
                                + " and t.reg_date > to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                + " and t.reg_date <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                + " and t.bill_no in("
                                + " select bill_no from T_BIZ_FUND_FLOW "
                                + " where ie_type='DC_INCOME'" + " ) group by c.COM_NAME", 0, 1000, param);
                Map<String, String> fundMap = new HashMap<String, String>();
                for (Object object : fundResult) {
                    Object[] objs = (Object[]) object;
                    fundMap.put(objs[1].toString(), objs[0].toString());
                }
                for (Object object : result) {
                    Object[] objs = (Object[]) object;
                    FundCustomerBizReport d = new FundCustomerBizReport(objs[1].toString(), objs[0].toString());
                    d.setFundAmount(fundMap.get(objs[1].toString()) == null ? "0.0" : fundMap
                            .get(objs[1].toString()));
                    customerBizReports.add(d);
                }
                Page<FundCustomerBizReport> page = new PageImpl<>(customerBizReports);
                return page;
            } catch (QueryException e) {
                e.printStackTrace();
            }
        }

        return null;
    }

    @RequestMapping("/report-findCustomerBizReport2")
    @ResponseBody
    public String findCustomerBizReport2(Jqgrid jqgrid) {
        List<FundCustomerBizReport> customerBizReports = new ArrayList<>();
        Filter filters = jqgrid.getFilters();
        String startDate = "";
        String endDate = "";
        if (null != filters && filters.getRules().size() > 0) {
            for (SearchRule rule : filters.getRules()) {
                if (rule.getField().equals("regDate")) {
                    if (rule.getOp().equals(SearchRuleOption.ge)) {
                        startDate = rule.getData().toString();
                    }
                    if (rule.getField().equals("regDate")) {
                        if (rule.getOp().equals(SearchRuleOption.le)) {
                            endDate = rule.getData().toString();
                        }
                    }
                }

            }
            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                if (StringUtils.isEmpty(startDate)) {
                    startDate = sdf.format(new Date(0));
                }
                if (StringUtils.isEmpty(endDate)) {
                    endDate = sdf.format(new Date());
                }
                Map<String, Object> param = new HashMap<String, Object>();
                param.put("supComId", LoginUtil.getLoginUser().getCompany().getId());
                param.put("startDate", startDate);
                param.put("endDate", endDate);
                List<Object> result = biz
                        .findObjectBySql("select count(*), c.com_name"
                                + " from t_biz_base_business b, t_biz_declaration d, t_sys_company c"
                                + " where b.id = d.id and b.customer_com_id = c.com_id and d.state not in ('DS00', 'DS03')"
                                + " and b.confirm_time > to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                + " and b.confirm_time <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                + " and b.sup_id =:supComId group by c.com_name", 0, 1000, param);
                List<Object> fundResult = biz
                        .findObjectBySql("select sum(amount), c.com_name from T_BIZ_FUND_FLOW t,t_sys_company c "
                                + " where t.com_id <> :supComId and t.com_id=c.com_id "
                                + " and t.regDate > to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                + " and t.regDate <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                + " and t.bill_no in("
                                + " select bill_no from T_BIZ_FUND_FLOW "
                                + " where com_id=:supComId "
                                + " and ie_type='DC_INCOME'"
                                + " ) group by c.COM_NAME", 0, 1000, param);
                Map<String, String> fundMap = new HashMap<String, String>();
                for (Object object : fundResult) {
                    Object[] objs = (Object[]) object;
                    fundMap.put(objs[1].toString(), objs[0].toString());
                }
                for (Object object : result) {
                    Object[] objs = (Object[]) object;
                    FundCustomerBizReport d = new FundCustomerBizReport(objs[1].toString(), objs[0].toString());
                    d.setFundAmount(fundMap.get(objs[1].toString()) == null ? "0.0" : fundMap
                            .get(objs[1].toString()));
                    customerBizReports.add(d);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return null;
    }


    @RequestMapping("/report-findCustomerBizReport")
    @ResponseBody
    public String findCustomerBizReport(FundFlow fundFlow, FundReport fundReport) {
        List<FundCustomerBizReport> customerBizReports = new ArrayList<>();
        if (null != fundFlow && StringUtils.isNotEmpty(fundFlow.getId())) {
            try {
                fundReport = biz.findEntityById(fundFlow.getId());
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Map<String, Object> param = new HashMap<String, Object>();
                param.put("supComId", LoginUtil.getLoginUser().getCompany().getId());
                param.put("startDate", sdf.format(fundReport.getPreRegDate()));
                param.put("endDate", sdf.format(fundReport.getRegDate()));
                List<Object> result = biz
                        .findObjectBySql("select count(*), c.com_name"
                                + " from t_biz_base_business b, t_biz_declaration d, t_sys_company c"
                                + " where b.id = d.id and b.customer_com_id = c.com_id and d.state not in ('DS00', 'DS03')"
                                + " and b.confirm_time > to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                + " and b.confirm_time <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                + " and b.sup_id =:supComId group by c.com_name", 0, 500, param);
                List<Object> fundResult = biz
                        .findObjectBySql("select sum(amount), c.com_name from T_BIZ_FUND_FLOW t,t_sys_company c "
                                + " where t.com_id <> :supComId and t.com_id=c.com_id "
                                + " and t.regDate > to_date(:startDate, 'yyyy-MM-dd hh24:mi:ss') "
                                + " and t.regDate <= to_date(:endDate, 'yyyy-MM-dd hh24:mi:ss')"
                                + " and t.bill_no in("
                                + " select bill_no from T_BIZ_FUND_FLOW "
                                + " where com_id=:supComId "
                                + " and ie_type='DC_INCOME'"
                                + " ) group by c.COM_NAME", 0, 500, param);
                Map<String, String> fundMap = new HashMap<String, String>();
                for (Object object : fundResult) {
                    Object[] objs = (Object[]) object;
                    fundMap.put(objs[1].toString(), objs[0].toString());
                }
                for (Object object : result) {
                    Object[] objs = (Object[]) object;
                    FundCustomerBizReport d = new FundCustomerBizReport(objs[1].toString(), objs[0]
                            .toString());
                    d.setFundAmount(fundMap.get(objs[1].toString()) == null ? "0.0" : fundMap
                            .get(objs[1].toString()));
                    customerBizReports.add(d);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 编辑信息
     */
    @RequestMapping("/report-find")
    @ResponseBody
    @Json({@JField("owner.name"), @JField("id"), @JField("preBalance"), @JField("preRegDate"), @JField("balance"),
            @JField("income"), @JField("cost"), @JField("remark"), @JField("regDate")})
    public FundReport find(FundFlow fundFlow, FundReport fundReport) {
        if (null != fundFlow && StringUtils.isNotEmpty(fundFlow.getId())) {
            try {
                fundReport = biz.findEntityById(fundFlow.getId());
                return fundReport;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    /**
     * 生成新一期报表
     */
    @RequestMapping("/report-buildReport")
    public Result buildReport() {
        Result msg;
        buildReport(LoginUtil.getLoginUser().getCompany());
        msg = Result.newSuccessInstance(MsgConstants.SAVE_SUECCES);
        return msg;
    }

    @Resource
    CompanyBiz companyBiz;

    /**
     * 生成新一期报表
     */
    @RequestMapping("/report-buildAllReport")
    @ResponseBody
    public Result buildAllReport() {
        Result msg;
        String startDateStr = HttpUtils.getRequest().getParameter("startDate");
        String endDateStr = HttpUtils.getRequest().getParameter("endDate");
        Date startDate = null;
        Date endDate = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat msdf = new SimpleDateFormat("yyyy-MM");
        try {
            startDate = sdf.parse(startDateStr);
            endDate = sdf.parse(endDateStr);

            startDate = msdf.parse(msdf.format(startDate));
            endDate = msdf.parse(msdf.format(endDate));
            Calendar ecal = Calendar.getInstance();
            ecal.setTime(endDate);
            ecal.add(Calendar.MONTH, 1);
            ecal.setTimeInMillis(ecal.getTimeInMillis() - 1);
            Calendar cal = Calendar.getInstance();
            cal.setTime(startDate);
            // cal.add(Calendar.MONTH, 1);
            // cal.setTimeInMillis(cal.getTimeInMillis() - 1);
            Calendar ncal = Calendar.getInstance();
            while (cal.getTimeInMillis() <= ecal.getTimeInMillis()) {
                ncal.setTime(cal.getTime());
                ncal.add(Calendar.MONTH, 1);
                ncal.setTimeInMillis(ncal.getTimeInMillis() - 1);
                buildAllReport(cal.getTime(), ncal.getTime());
                cal.add(Calendar.MONTH, 1);
            }
            msg = Result.newSuccessInstance(MsgConstants.SAVE_SUECCES);
        } catch (Exception e) {
            e.printStackTrace();
            msg = Result.newFailInstance(MsgConstants.SAVE_FAIL);
        }
        return msg;
    }

    @Autowired
    FundFlowBiz fundFlowBiz;

    private List<FundReport> buildAllReport(Date startDate, Date endDate) {
        List<FundReport> results = new ArrayList<FundReport>();
        // mark time period
        Date now = endDate;
        // get income
        // get cost
        String income = "";
        String cost = "";
        Map<String, Object> parameters = new HashMap<String, Object>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // parameters.put("ENDDATE", sdf.format(now));
        // parameters.put("STARTDATE", sdf.format(startDate));
        String sql = "SELECT SUM(AMOUNT), COM_ID from (SELECT * FROM T_BIZ_FUND_FLOW WHERE FINANCIAL_TYPE=:FTYPE AND REG_DATE <= to_date('"
                + sdf.format(now)
                + "','yyyy-mm-dd hh24:mi:ss') AND REG_DATE > to_date('"
                + sdf.format(startDate) + "','yyyy-mm-dd hh24:mi:ss')) group by COM_ID";
        try {
            parameters.put("FTYPE", FundFinancialTypeEnum.IN.toString());
            List<Object> incomeResults = fundFlowBiz.findObjectBySql(sql, 0, 1000, parameters);
            parameters.put("FTYPE", FundFinancialTypeEnum.OUT.toString());
            List<Object> costResults = fundFlowBiz.findObjectBySql(sql, 0, 1000, parameters);

            Set<String> comIdSet = new HashSet<String>();
            Map<String, String> incomeMap = new HashMap<String, String>();
            Map<String, String> costMap = new HashMap<String, String>();
            for (Object object : incomeResults) {
                Object[] obj = (Object[]) object;
                if (obj[1] != null) {
                    comIdSet.add(obj[1].toString());
                    incomeMap.put(obj[1].toString(), obj[0].toString());
                }
            }
            for (Object object : costResults) {
                Object[] obj = (Object[]) object;
                if (obj[1] != null) {
                    comIdSet.add(obj[1].toString());
                    costMap.put(obj[1].toString(), obj[0].toString());
                }
            }

            List<FundReport> latestReport = biz
                    .findEntityByHql("select a from com.mrd.gtimp.business.pojo.FundReport a where not exists(select 1 from com.mrd.gtimp.business.pojo.FundReport b where b.owner = a.owner and b.regDate > a.regDate) ", 0, 1000, null);
            Map<String, FundReport> latestReportMap = new HashMap<String, FundReport>();
            for (FundReport fundReport : latestReport) {
                latestReportMap.put(fundReport.getOwner().getId(), fundReport);
            }

            for (Iterator<String> it = comIdSet.iterator(); it.hasNext(); ) {
                String key = it.next();
                FundReport lreport = latestReportMap.get(key);
                income = incomeMap.get(key) == null ? "0.0" : incomeMap.get(key);
                cost = costMap.get(key) == null ? "0.0" : costMap.get(key);
                // insert
                FundReport result = new FundReport();
                Company c = new Company();
                c.setId(key);
                result.setPreBalance(lreport == null ? 0.0 : lreport.getBalance());
                result.setPreRegDate(lreport == null ? new Date(0) : new Date(lreport.getRegDate()
                        .getTime() + 1000));
                result.setRegDate(now);
                result.setOwner(c);
                result.setIncome(Double.parseDouble(income));
                result.setCost(Double.parseDouble(cost));
                result.setBalance(result.getPreBalance() + result.getIncome() - result.getCost());
                results.add(result);
            }
            biz.getBaseRepository().saveEntities(results);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return results;
    }

    private FundReport buildReport(Company owner, Date endDate) {
        FundReport result = new FundReport();
        // mark time period
        Date now = endDate;
        FundReport entity = biz.findLatestReport(owner);
        Date startDate;
        if (entity == null) {
            startDate = new Date(0);
            result.setPreBalance(0);
            result.setPreRegDate(startDate);
        } else {
            System.out.println("find latest report" + entity);
            startDate = entity.getRegDate();
            result.setPreBalance(entity.getBalance());
            result.setPreRegDate(entity.getRegDate());
        }
        // get income
        // get cost
        String income = "";
        String cost = "";
        Map<String, Object> parameters = new HashMap<String, Object>();
        parameters.put("COMID", owner.getId());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        // parameters.put("ENDDATE", sdf.format(now));
        // parameters.put("STARTDATE", sdf.format(startDate));
        String sql = "SELECT SUM(AMOUNT) FROM T_BIZ_FUND_FLOW WHERE FINANCIAL_TYPE=:FTYPE AND COM_ID=:COMID AND REG_DATE <= to_date('"
                + sdf.format(now)
                + "','yyyy-mm-dd hh24:mi:ss') AND REG_DATE > to_date('"
                + sdf.format(startDate) + "','yyyy-mm-dd hh24:mi:ss')";
        try {
            parameters.put("FTYPE", FundFinancialTypeEnum.IN.toString());
            List<Object> incomeResults = fundFlowBiz.findObjectBySql(sql, 1, 1, parameters);
            income = incomeResults == null || incomeResults.size() == 0
                    || incomeResults.get(0) == null ? "0.0" : incomeResults.get(0).toString();
            parameters.put("FTYPE", FundFinancialTypeEnum.OUT.toString());
            List<Object> costResults = fundFlowBiz.findObjectBySql(sql, 1, 1, parameters);
            cost = costResults == null || costResults.size() == 0 || costResults.get(0) == null ? "0.0"
                    : costResults.get(0).toString();
            // insert
            result.setRegDate(now);
            result.setOwner(owner);
            result.setIncome(Double.parseDouble(income));
            result.setCost(Double.parseDouble(cost));
            result.setBalance(result.getPreBalance() + result.getIncome() - result.getCost());
            biz.saveOrupdateEntity(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    private FundReport buildReport(Company owner) {
        // mark time period
        return buildReport(owner, new Date());
    }

    @RequestMapping("/report-delReport")
    @ResponseBody
    public Result delReport() {
        Result msg;
        biz.delReport(LoginUtil.getLoginUser().getCompany());
        msg = Result.newSuccessInstance(MsgConstants.OPERATION_SUCCESS);
        return msg;
    }

    @RequestMapping("/report-findList")
    @ResponseBody
    @Json({@JField("owner.name"), @JField("id"), @JField("preBalance"), @JField("preRegDate"), @JField("balance"),
            @JField("income"), @JField("cost"), @JField("remark"), @JField("regDate")})
    public Page<FundReport> findList(Jqgrid jqgrid) {
        String comId = LoginUtil.getLoginUser().getCompany().getId();// get from user
        try {
//        if (null == filters) {
//            filters = new Filter();
//            filters.setGroupOp(FilterGroupOption.AND);
//        }
            SearchRule rule = new SearchRule("owner.id", SearchRuleOption.eq, comId);
            jqgrid.addRule(rule);
            findManagerList(jqgrid);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @RequestMapping("/report-findManagerList")
    @ResponseBody
    @Json({@JField("owner.name"), @JField("id"), @JField("preBalance"), @JField("preRegDate"), @JField("balance"),
            @JField("income"), @JField("cost"), @JField("remark"), @JField("regDate")})
    public Page<FundReport> findManagerList(Jqgrid jqgrid) {
        try {
//            page = initPage(biz.findEntityCount(filters));
//            Order order = new Order();
//            if (null != sidx && !"".equals(sidx)) {
//                order.add(sidx, sord);
//            }
            Page<FundReport> page = biz.findByJqgrid(jqgrid);
            if (page.getSize() > 0) {
                return page;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public FundReportBiz getBiz() {
        return biz;
    }

    public void setBiz(FundReportBiz biz) {
        this.biz = biz;
    }


}
